import librosa
import soundfile as sf
import io
import tempfile
from typing import Tuple, Union

def pitch_shift_audio(input_file, output_file, n_steps=12):
    """
    将音频音调升高指定半音数
    
    Args:
        input_file: 输入音频文件路径
        output_file: 输出音频文件路径
        n_steps: 升高的半音数，12个半音 = 一个八度（音调升高一倍）
    """
    # 加载音频文件
    y, sr = librosa.load(input_file, sr=None)
    
    # 将音调升高指定半音数
    y_shifted = librosa.effects.pitch_shift(y, sr=sr, n_steps=n_steps)
    
    # 保存处理后的音频文件
    sf.write(output_file, y_shifted, sr)
    print(f"音调已升高 {n_steps} 个半音，保存到: {output_file}")

def pitch_shift_audio_bytes(audio_data: bytes, n_steps: int = 12) -> Tuple[bytes, int]:
    """
    处理音频字节数据，进行音调调节
    
    Args:
        audio_data: 音频文件的字节数据
        n_steps: 音调调节的半音数，正数升高，负数降低
    
    Returns:
        Tuple[bytes, int]: 处理后的音频字节数据和采样率
    """
    # 使用临时文件处理音频数据
    with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temp_input:
        temp_input.write(audio_data)
        temp_input.flush()
        
        try:
            # 加载音频文件
            y, sr = librosa.load(temp_input.name, sr=None)
            
            # 进行音调调节
            y_shifted = librosa.effects.pitch_shift(y, sr=sr, n_steps=n_steps)
            
            # 将处理后的音频保存到内存
            with io.BytesIO() as output_buffer:
                sf.write(output_buffer, y_shifted, sr, format='WAV')
                output_buffer.seek(0)
                return output_buffer.getvalue(), sr
                
        finally:
            # 清理临时文件
            import os
            try:
                os.unlink(temp_input.name)
            except:
                pass

# 使用示例
if __name__ == "__main__":
    input_file = 'meirenyu_pianduan.mp3'
    output_file = 'meirenyu_pianduan_pitch_shifted.mp3'
    
    # 升高12个半音（一个八度，即音调升高一倍）
    pitch_shift_audio(input_file, output_file, n_steps=12)
